import requests
import json
import re
import os
import time
from tqdm import tqdm
from concurrent.futures import ThreadPoolExecutor

def kuaishou(userId):
    headers ={
        'content-type': 'application/json',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
        'Cookie': 'did=web_abc05c6ae50d7971ab544b3e00c4529a; didv=1735206769886; _bl_uid=g1mmL5je5CX55gbg83L2zsXvwpj0; kpf=PC_WEB; clientid=3; kpn=KUAISHOU_VISION',
        'Referer': 'https://www.kuaishou.com/profile/'+userId
    }
    url = 'https://www.kuaishou.com/graphql'
    data = {
        'operationName': 'visionProfilePhotoList',
        'query': "fragment photoContent on PhotoEntity {\n  __typename\n  id\n  duration\n  caption\n  originCaption\n  likeCount\n  viewCount\n  commentCount\n  realLikeCount\n  coverUrl\n  photoUrl\n  photoH265Url\n  manifest\n  manifestH265\n  videoResource\n  coverUrls {\n    url\n    __typename\n  }\n  timestamp\n  expTag\n  animatedCoverUrl\n  distance\n  videoRatio\n  liked\n  stereoType\n  profileUserTopPhoto\n  musicBlocked\n  riskTagContent\n  riskTagUrl\n}\n\nfragment recoPhotoFragment on recoPhotoEntity {\n  __typename\n  id\n  duration\n  caption\n  originCaption\n  likeCount\n  viewCount\n  commentCount\n  realLikeCount\n  coverUrl\n  photoUrl\n  photoH265Url\n  manifest\n  manifestH265\n  videoResource\n  coverUrls {\n    url\n    __typename\n  }\n  timestamp\n  expTag\n  animatedCoverUrl\n  distance\n  videoRatio\n  liked\n  stereoType\n  profileUserTopPhoto\n  musicBlocked\n  riskTagContent\n  riskTagUrl\n}\n\nfragment feedContentWithLiveInfo on Feed {\n  type\n  author {\n    id\n    name\n    headerUrl\n    following\n    livingInfo\n    headerUrls {\n      url\n      __typename\n    }\n    __typename\n  }\n  photo {\n    ...photoContent\n    ...recoPhotoFragment\n    __typename\n  }\n  canAddComment\n  llsid\n  status\n  currentPcursor\n  tags {\n    type\n    name\n    __typename\n  }\n  __typename\n}\n\nquery visionProfilePhotoList($pcursor: String, $userId: String, $page: String, $webPageArea: String) {\n  visionProfilePhotoList(pcursor: $pcursor, userId: $userId, page: $page, webPageArea: $webPageArea) {\n    result\n    llsid\n    webPageArea\n    feeds {\n      ...feedContentWithLiveInfo\n      __typename\n    }\n    hostName\n    pcursor\n    __typename\n  }\n}\n",
        'variables': {
            'page': 'profile',
            'pcursor': '1.732634751467E12',
            'userId': userId,
        }
    }
    data = json.dumps(data)
    res_json = requests.post(url,headers=headers,data=data).json()
    feeds = res_json['data']['visionProfilePhotoList']['feeds']
    with ThreadPoolExecutor(20) as pool:
        for feed in tqdm(feeds):
            pool.submit(Download,feed)
    print(len(feeds),'个视频已下载完成')

def Download(feed):
    caption = feed['photo']['caption']
    photoUrl = feed['photo']['photoUrl']
    caption = filter_special_characters(caption)
    folder_path = "./kuaishou"
    # 检查文件夹是否存在
    if not os.path.exists(folder_path):
        os.makedirs(folder_path)
    osss = folder_path + "/" + caption
    res = requests.get(photoUrl)
    with open(osss + ".mp4", 'wb') as f:
        f.write(res.content)
        print(caption, "下载成功！")

def filter_special_characters(text):
    pattern = re.compile('[^\\w\\s]')
    filtered_text = re.sub(pattern, '', text)
    filtered_texts = filtered_text.replace(" ", "-").replace("\n", "")#去掉空格换行
    return filtered_texts

if __name__ == '__main__':
    start_time = time.time()
    userId = '3xekn2qhp4htha2'
    kuaishou(userId)
    print('一共花费了：', time.time() - start_time)